#include <stdio.h>
#include <iostream>
#include <string>
#include <sstream>
#include <stdlib.h>

using namespace std;
#define PEG_NUM 4

int D;
string generate_hanoi_rule(int src, int des, int d);

string convertInt(int number)
{
   ostringstream ss;//create a stringstream
   ss << number;//add number to the stream
   return ss.str();//return a string with the contents of the stream
}

int main(int argc, char *argv[])
{
    if (argc < 2)
    {
      cout << "provide D as an argument please." <<endl;
      return -1;
    }

    D=atoi(argv[1]);
    string havij;

    havij=havij+convertInt(D*PEG_NUM)+"\n\n";
    for (int i=0;i<D*PEG_NUM;i++)
	havij=havij+"2 ";

    havij=havij+"\n\n";

    for (int d=0; d<D; d++)
    {
        for (int i=0; i<PEG_NUM;i++)
        {
            for(int j=0;j<PEG_NUM;j++)
            {
                if (i==j)
                    continue;
                havij=havij+generate_hanoi_rule(i,j,d);//source_col, dest_col, disk
            }
        }
    }
    havij=havij+"\nGOAL ";
    for (int i=0;i<PEG_NUM*D;i++)
    {
        if(i < (PEG_NUM-1)*D)
            havij=havij+ "0 ";
        else
            havij=havij+ "1 ";
    }
    havij=havij+"\n";
    cout << havij;


}


string generate_hanoi_rule(int src, int des, int d)
{
    string tstr1="";
    string tstr2="";
    int rev_flag= 0;
    if (src < des)
    {
        rev_flag= 1;
        int tmp= src;
        src= des;
        des=tmp;
    }
    for (int i=0; i< PEG_NUM*D; i++)
    {
        tstr1.append("- ");
        tstr2.append("- ");
    }
    for (int i=0; i<d; i++)
    {
        tstr1[2*(src*D+i)]='0';
        tstr1[2*(src*D+i)+1]=' ';
        tstr2[2*(src*D+i)]='0';
        tstr2[2*(src*D+i)+1]=' ';
        tstr1[2*(des*D+i)]='0';
        tstr1[2*(des*D+i)+1]=' ';
        tstr2[2*(des*D+i)]='0';
        tstr2[2*(des*D+i)+1]=' ';
    }
    if(!rev_flag)
    {
        tstr1.replace(2*(src*D+d),2, "1 ");
        tstr1.replace(2*(des*D+d),2, "0 ");
        tstr2.replace(2*(src*D+d),2, "0 ");
        tstr2.replace(2*(des*D+d),2, "1 ");
    }
    else
    {
        tstr1.replace(2*(src*D+d),2, "0 ");
        tstr1.replace(2*(des*D+d),2, "1 ");
        tstr2.replace(2*(src*D+d),2, "1 ");
        tstr2.replace(2*(des*D+d),2, "0 ");
    }
    tstr1=tstr1+"=> "+tstr2+"\n";
    return tstr1;
}

/*
 * Generates K-Disk 4-Peg Towers of Hanoi
 * Originally Written by Meysam Bastani
 * Modified by Shahab Jabbari
 * There are 4 binary variables assigned for each disk
 * These variables are used to identify the location of each disk
 * I.e., when these variables are "0 0 1 0" for a disk, it means
 * that the disk is on the third peg
 * Knowing the disks in one peg is enough to model each state since
 * disks that are on the same peg can only have one specific order
*/
